﻿/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Discribe：实现UI上的标签可以跟随3D场景的物体移动效果
* CreateTime：2020-05-18 11:06:18
* Version：1.0
* Modify Recoder：
*************************************************/

using UnityEngine;

namespace TinyToolKit
{
    public class BillBoard : TMonoSingleton<BillBoard>
    {
        public GameObject itemPrefab;
        public Camera UICamera;
        public RectTransform camvasRectTf;
        public Transform ItemsRoot;
        
        private Transform[] targetTfs;
        private BillBoardItem[] billBoardItems;
        private bool showBillBoard;

        private void Start() 
        {
            if (ItemsRoot == null)
                ItemsRoot = this.transform;

            if(UICamera == null)
                UICamera = Camera.main;
            
            if (camvasRectTf == null)
                camvasRectTf = GameObject.Find("Canvas").GetComponent<RectTransform>();
        }

        private void Update()
        {
            if (showBillBoard)
            {
                UpdatePosition();
            }
        }

        #region Public Func
        public void ShowBillBoard(Transform[] billBoardTf)
        {
            if (billBoardTf == null || billBoardTf.Length <= 0) return;
            SetBillBoardTarget(billBoardTf);
            ShowBillBoard(true); 
        }

        public void HideBillBoard() 
        {
            ShowBillBoard(false);
        }
        #endregion
      

        #region Internal Func
        private void SetBillBoardTarget(Transform[] targetTfs)
        {
            if (billBoardItems != null && billBoardItems.Length > 0)
            {
                for (int i = 0; i < billBoardItems.Length; i++)
                {
                    Destroy(billBoardItems[i].gameObject);
                }
            }

            this.targetTfs = targetTfs;
            int count = targetTfs.Length;
            billBoardItems = new BillBoardItem[count];

            for (int i = 0; i < count; i++)
            {
                GameObject tempObj = Instantiate(itemPrefab, ItemsRoot);
                tempObj.transform.localScale = Vector3.one;
                tempObj.transform.localPosition = Vector3.one * 1000;
                BillBoardItem boardItem = tempObj.GetOrAddComponent<BillBoardItem>();
                billBoardItems[i] = boardItem; 
                boardItem.OnSpawn(targetTfs[i]);
            }
        }

        private void ShowBillBoard(bool show)
        {
            showBillBoard = show;

            for (int i = 0; i < targetTfs.Length; i++)
            {
                billBoardItems[i].TweenAnim(show);
            }
        }

        private void UpdatePosition()
        {
            for (int i = 0; i < targetTfs.Length; i++)
            { 
                var screenPos = UICamera.WorldToScreenPoint(targetTfs[i].position);
                if (RectTransformUtility.ScreenPointToLocalPointInRectangle(camvasRectTf, screenPos, null,
                    out var localPoint))
                {
                    billBoardItems[i].SetPosition(localPoint);
                }
            }
        }
        #endregion
    }
}